package com.fast.fast.common.jpa.service;

import com.fast.fast.common.base.page.PageResultForJpa;

import java.io.Serializable;
import java.util.List;

/**
 * JPA自定义封装接口
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 */
public interface JpaService<T> {

    /**
     * 增加单个----根据对象
     *
     * @param o
     */
    void save(Object o);

    /**
     * 增加单个----根据id
     *
     * @param poClass
     * @param id
     */
    void save(Class<T> poClass, Serializable id);

    /**
     * 增加多个----根据对象
     *
     * @param o
     */
    void saveAll(Object[] o);

    /**
     * 增加多个----根据ids
     *
     * @param poClass
     * @param ids
     */
    void saveAll(Class<T> poClass, Serializable[] ids);

    /**
     * 删除单个----根据对象
     *
     * @param o
     */
    void del(Object o);

    /**
     * 删除单个----根据id
     *
     * @param poClass
     * @param id
     */
    void del(Class<T> poClass, Serializable id);

    /**
     * 删除多个----根据对象
     *
     * @param o
     */
    void delAll(Object[] o);

    /**
     * 删除多个----根据ids
     *
     * @param poClass
     * @param ids
     */
    void delAll(Class<T> poClass, Serializable[] ids);

    /**
     * 修改单个----根据对象
     *
     * @param o
     */
    void update(Object o);

    /**
     * 修改单个----根据id
     *
     * @param poClass
     * @param id
     */
    void update(Class<T> poClass, Serializable id);

    /**
     * 修改多个----根据对象
     *
     * @param o
     */
    void updateAll(Object[] o);

    /**
     * 修改多个----根据ids
     *
     * @param poClass
     * @param ids
     */
    void updateAll(Class<T> poClass, Serializable[] ids);

    /**
     * 原生sql数据库DML操作----可加条件
     *
     * @param sql
     * @param o
     * @return
     */
    int executeSql(String sql, Object[] o);

    /**************************************** 以下查询 *********************************************/

    /**************************************** hql单个查询 *********************************************/

    /**
     * load查询单个----根据id
     *
     * @param poClass
     * @param id
     * @return
     */
    T load(Class<T> poClass, Serializable id);

    /**
     * load查询多个----根据ids
     *
     * @param poClass
     * @param ids
     * @return
     */
    List<T> loadAll(Class<T> poClass, Serializable[] ids);

    /**
     * get查询单个----根据id
     *
     * @param poClass
     * @param id
     * @return
     */
    T get(Class<T> poClass, Serializable id);

    /**
     * get查询多个----根据ids
     *
     * @param poClass
     * @param ids
     * @return
     */
    List<T> getAll(Class<T> poClass, Serializable[] ids);

    /**
     * hql查询----唯一查询----可加条件
     *
     * @param hql
     * @param o
     * @return
     */
    Object findOne(String hql, Object[] o);

    /**************************************** hql批量查询 *********************************************/
    /**
     * hql查询----可加条件
     *
     * @param hql
     * @param o
     * @return
     */
    List find(String hql, Object[] o);

    /**
     * hql查询----可加条件,max为查询几条
     *
     * @param hql
     * @param o
     * @param max
     * @return
     */
    List find(String hql, Object[] o, Integer max);

    /**
     * hql分页查询----可加条件
     *
     * @param hql
     * @param page
     * @param o
     * @return
     */
    List findByPage(String hql, PageResultForJpa<T> page, Object[] o);

    /**
     * hql投影查询----可加条件----需写select----查询出来的是对象的属性
     * 如select name-->List<String>;select name,age-->List<Object[]>
     *
     * @param hql
     * @param o
     * @return
     */
    List findAttr(String hql, Object[] o);

    /**************************************** 原生sql查询 *********************************************/
    /**
     * 原生sql查询----可加条件----类似hql投影查询,泛型不能是po对象
     *
     * @param sql
     * @param o
     * @return
     */
    List findBySql(String sql, Object[] o);//

    /**
     * 原生sql查询----可加条件----类似hql投影查询,泛型不能是po对象----max为查询几条
     *
     * @param sql
     * @param o
     * @param max
     * @return
     */
    List findBySql(String sql, Object[] o, Integer max);

    /**
     * 原生sql查询----可加条件----Object转换成具体对象
     *
     * @param poClass
     * @param sql
     * @param o
     * @return
     */
    List findBySql(Class<T> poClass, String sql, Object[] o);

    /**
     * 原生sql查询----可加条件----Object转换成具体对象----max为查询几条
     *
     * @param poClass
     * @param sql
     * @param o
     * @param max
     * @return
     */
    List findBySql(Class<T> poClass, String sql, Object[] o, Integer max);

    /**
     * 原生sql查询将结果放入实体----可加条件----不需要有表,不需要配置注解或xml,只需要与查询结果对应字段的视图实体,但视图实体字段的名字和类型必须和表里的字段完全匹配.当类型不确定时可用Object代替
     *
     * @param poClass
     * @param sql
     * @param o
     * @return
     */
    List findBySqlNoMapping(Class<T> poClass, String sql, Object[] o);

    /**
     * 原生sql查询将结果放入实体----可加条件----不需要有表,不需要配置注解或xml,只需要与查询结果对应字段的视图实体,但视图实体字段的名字和类型必须和表里的字段完全匹配.当类型不确定时可用Object代替----max为查询几条
     *
     * @param poClass
     * @param sql
     * @param o
     * @param max
     * @return
     */
    List findBySqlNoMapping(Class<T> poClass, String sql, Object[] o, Integer max);

    /***************** 原生sql分页查询 *****************/

    /**
     * 原生sql分页查询----可加条件----Object转换成具体对象
     *
     * @param poClass
     * @param sql
     * @param page
     * @param o
     * @return
     */
    List findBySqlPage(Class<T> poClass, String sql, PageResultForJpa<T> page, Object[] o);

    /**
     * 原生sql分页查询将结果放入实体----可加条件----Object转换成具体对象----不需要有表,不需要配置注解或xml,只需要与查询结果对应字段的实体,但视图实体字段的名字和类型必须和表里的字段完全匹配.当类型不确定时可用Object代替
     *
     * @param poClass
     * @param sql
     * @param page
     * @param o
     * @return
     */
    List findBySqlNoMappingPage(Class<T> poClass, String sql, PageResultForJpa<T> page, Object[] o);

    /***************** 原生sql唯一查询 *****************/
    /**
     * 原生sql查询----唯一查询----可加条件----Object不能是po对象
     *
     * @param sql
     * @param o
     * @return
     */
    Object findOneBySql(String sql, Object[] o);

    /**
     * 原生sql查询----唯一查询----可加条件----Object转换成具体对象
     *
     * @param poClass
     * @param sql
     * @param o
     * @return
     */
    Object findOneBySql(Class<T> poClass, String sql, Object[] o);

    /**
     * 原生sql查询将结果放入实体----唯一查询----可加条件----不需要有表,不需要配置注解或xml,只需要与查询结果对应字段的视图实体,但视图实体字段的名字和类型必须和表里的字段完全匹配.当类型不确定时可用Object代替
     *
     * @param poClass
     * @param sql
     * @param o
     * @return
     */
    Object findOneBySqlNoMapping(Class<T> poClass, String sql, Object[] o);
}
